package cn.xuan.scan.dao.query.param;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

public class QueryTree implements Serializable {
	String token_left = "[";
	String token_right = "]";
	String token_dot = ",";
	private HashMap parenChildrenMap = new HashMap();
	private HashMap azPranentgetFiledMap = new HashMap();
	private Vector azClsPairs = new Vector();
	private Class rootClass;

	public QueryTree(Class rootClass) {
		this.rootClass = rootClass;
	}

	public void addQueryPath(String query) {
		if (this.isDeepPath(query)) {
			Vector pairs = ParseTree.parseString(query);
			Iterator it = pairs.iterator();

			while (it.hasNext()) {
				String queryPair = (String) it.next();
				this.parseClass(queryPair);
			}
		} else {
			this.parseClass(query);
		}

	}

	private boolean parseClass(String query) {
		if (!this.checkInputQueryFormat(query)) {
			return false;
		} else {
			StringTokenizer queryToken_left = new StringTokenizer(query, this.token_left);
			boolean isParen = true;
			String strParent = null;
			String parentClassName = null;
			HashSet vtChildrenCls = new HashSet();

			label38 : do {
				while (queryToken_left.hasMoreElements()) {
					if (isParen) {
						isParen = false;
						strParent = (String) queryToken_left.nextElement();
						strParent = strParent.trim();
						parentClassName = strParent;
						continue label38;
					}

					if (this.parenChildrenMap.get(parentClassName) != null) {
						vtChildrenCls = (HashSet) this.parenChildrenMap.get(parentClassName);
					} else {
						this.parenChildrenMap.put(parentClassName, vtChildrenCls);
					}

					String strchildren = (String) queryToken_left.nextElement();
					strchildren = (String) (new StringTokenizer(strchildren, this.token_right)).nextElement();
					StringTokenizer queryToken_dot = new StringTokenizer(strchildren, this.token_dot);

					while (queryToken_dot.hasMoreElements()) {
						String strChild = (String) queryToken_dot.nextElement();
						strChild = strChild.trim();
						vtChildrenCls.add(strChild);
					}
				}

				return true;
			} while (strParent != null && !strParent.equals(""));

			System.out.println("Parent ClassName is null");
			return false;
		}
	}

	private boolean checkInputQueryFormat(String query) {
		if (query != null && !query.equals("")) {
			StringTokenizer queryToken_left = new StringTokenizer(query, this.token_left);
			if (queryToken_left.countTokens() != 2) {
				System.out.println(query + ":" + " does not include " + this.token_left + " or has more than one");
				return false;
			} else {
				StringTokenizer queryToken_right = new StringTokenizer(query, this.token_right);
				if (queryToken_right.countTokens() != 1) {
					System.out
							.println(query + ":" + " does not end with " + this.token_right + " or has more than one");
					return false;
				} else if (query.indexOf(this.token_left) < query.indexOf(this.token_right)
						&& query.indexOf(this.token_left) > 0) {
					if (query.indexOf(this.token_left + this.token_dot) < 0
							&& query.indexOf(this.token_dot + this.token_right) < 0) {
						return true;
					} else {
						System.out.println(query + ":" + " does not have a valid format with" + this.token_dot + " "
								+ this.token_left);
						return false;
					}
				} else {
					System.out.println(query + ":" + this.token_left + " must before " + this.token_right);
					return false;
				}
			}
		} else {
			return false;
		}
	}

	private boolean isDeepPath(String query) {
		String judger1 = this.token_left + this.token_left;
		String judger2 = this.token_right + this.token_right;
		String judger3 = this.token_right + this.token_left;
		String judger4 = this.token_right + " " + this.token_left;
		String judger5 = this.token_left + " " + this.token_left;
		String judger6 = this.token_right + " " + this.token_right;
		if (query.indexOf(judger1) >= 0) {
			return true;
		} else if (query.indexOf(judger2) >= 0) {
			return true;
		} else if (query.indexOf(judger3) >= 0) {
			return true;
		} else if (query.indexOf(judger4) >= 0) {
			return true;
		} else if (query.indexOf(judger5) >= 0) {
			return true;
		} else {
			return query.indexOf(judger6) >= 0;
		}
	}

	public HashMap getParenChildrenMap() {
		return this.parenChildrenMap;
	}

	public Class getRootClass() {
		return this.rootClass;
	}

	public Vector getAzClsPairs() {
		return this.azClsPairs;
	}

	public HashMap getAzPranentgetFiledMap() {
		return this.azPranentgetFiledMap;
	}
}
